package util

import "fmt"

/* 指针地址和指针类型 */
/*
每个变量在运行时都拥有一个地址，这个地址代表变量在内存中的位置。Go语言中使用&字符放在变量前面对变量进行“取地址”操作。
 Go语言中的值类型（int、float、bool、string、array、struct）都有对应的指针类型，如：*int、*int64、*string等。

	取变量指针的语法如下：
	```
	ptr := &v    // v的类型为T
	```
	其中：
	v:代表被取地址的变量，类型为T
	ptr:用于接收地址的变量，ptr的类型就为*T，称做T的指针类型。*代表指针。
*/
func Test1() {
	a := 10
	b := &a
	fmt.Printf("a: %v pointAddress: %p\n", a, &a)
	fmt.Printf("b: %v type:%T\n", b, b)
	fmt.Printf("b pointAddress: %p\n", &b)
}

/*
指针取值
在对普通变量使用&操作符取地址后会获得这个变量的指针，然后可以对指针使用*操作，也就是指针取值，代码如下。
*/
func Test2() {
	a := 10
	b := &a // 取变量a的地址，将指针保存到b中
	fmt.Printf("type of b: %T\n", b)
	c := *b // 指针取值（根据指针去内存取值）
	fmt.Printf("type of c: %T\n", c)
	fmt.Printf("c: %v\n", c)
}

/*
总结： 取地址操作符&和取值操作符*是一对互补操作符，&取出地址，*根据地址取出地址指向的值。

变量、指针地址、指针变量、取地址、取值的相互关系和特性如下：

对变量进行取地址（&）操作，可以获得这个变量的指针变量。
指针变量的值是指针地址。
对指针变量进行取值（*）操作，可以获得指针变量指向的原变量的值。

*/

func modify1(x int) {
	x = 100
}

func modify2(x *int) {
	*x = 100
}

func Test3() {
	a := 10
	modify1(a)
	fmt.Println(a) // 10
	modify2(&a)
	fmt.Println(a) // 100
}
